<?php
/**
 * 记录操作日志
 *
 * @date    2018-09-17 18:13:50
 * @version $Id$
 */

namespace App\Http\Middleware;

use App;
use App\Commons\Libs\Annotations\UserLog;
use Arr;
use Browser;
use Closure;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\StreamedResponse;

class ActionLog
{
    public function handle($request, Closure $next)
    {
        return $next($request);
    }

    public function terminate($request, $response)
    {
        if (App::environment('local')
            || $response instanceof StreamedResponse
            || $response instanceof BinaryFileResponse) {
            return;
        }
        $route = request()->route();
        $user = auth()->user();
        if (empty($user) && $request->has('uid')) {
            auth()->guard()->byId($request->get('uid'));
            $user = auth()->guard()->getUser();
        }
        $data = [];
        $data['status'] = $response instanceof Response ? $response->getStatusCode() : $response->status();
        if ($route && in_array($request->method(), ['GET', 'POST','PUT','DELETE']) && $user) {
            $data['user_id'] = $user['uid'] ?? '';
            $data['controller'] = $route->getActionName();
            $data['method'] = $request->method();
            $data['url'] = str_replace($request->url(), $request->path(), $request->fullUrl());
            $data['params'] = json_encode($request->all());
            $data['created_at'] = date('Y-m-d H:i:s');
            $data['updated_at'] = date('Y-m-d H:i:s');
            $data['referrer'] = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : $request->fullUrl();
            $data['data'] = ($response instanceof JsonResponse) ? $response->getData(true) :$response->getContent();
            if (is_string($data['data'])) {
                $data['data'] = json_decode($data['data'], true);
            }
            Arr::forget($data, 'data._debugbar');
            $data['app_name'] = config('app.name', '');
            // \Storage::put('action.log', json_encode($data));
            logs('trace')->info($request->fullUrl(), $data);
            // TODO: 发送日志到kafka处理
        }

        if ($route && in_array($request->method(), ['GET', 'POST','PUT','DELETE'])) {
            // 处理
            rescue(
                function () use ($route, $request, $data) {
                    $this->captureUserLog($route->getAction(), $request, $data);
                },
                function ($e) use ($data) {
                    logs('daily')->info($e->getTraceAsString());
                },
                false
            );
        }
    }

    /**
     * 记录用户日志
     * @param  User $user    用户对象
     * @param  Request $request 请求对象
     * @param  array  $data    日志数据
     * @return [type]          [description]
     */
    private function captureUserLog($action, $request, array $data)
    {
        $action = $action['uses'];
        // 判断成功或失败
        $annotation = UserLog::annotation($action);
        if (empty($annotation)) {
            return;
        }

        $success = intval($data['status']) === 200 && intval(Arr::get($data, 'data.code', -1)) === 0;
        $ip = $request->ip();
        $browser = Browser::detect();
        $device = $browser->platformName() . ', '. $browser->deviceFamily();

        logs('user-log')->info(json_encode($annotation + $data, JSON_UNESCAPED_UNICODE));
        // app(SystemService::class)->addLog($ip, $device, $annotation['type'], $annotation['note'], $success ? 0: -1);
        // TODO: 发送日志到kafka处理
    }
}
